#include "CheckingAccount.hh"
#include "Transaction.hh"

void CheckingAccount::deposit(double amount, const std::string& note) {
    if (amount > 0) {
        balance += amount;
        Transaction transaction(amount, "Deposit", note);
        recordTransaction(transaction);
    } else {
        std::cout << "Invalid deposit amount.\n";
    }
}

void CheckingAccount::withdraw(double amount, const std::string& note) {
    if (amount > 0 && balance >= amount) {
        balance -= amount;
        Transaction transaction(-amount, "Withdrawal", note);
        recordTransaction(transaction);
    } else {
        std::cout << "Insufficient funds or invalid withdrawal amount.\n";
    }
}

void CheckingAccount::transfer(Account* to, double amount, const std::string& note) {
    if (amount > 0 && balance >= amount) {
        balance -= amount;
        std::cout << "Transfering to account: " <<"\n";
        to->deposit(amount, note);
        Transaction transaction(-amount, "Transfer", note);
        recordTransaction(transaction);
    } else {
        std::cout << "Insufficient funds or invalid transfer amount.\n";
    }
}

void CheckingAccount::setBank(Bank* bank) {
    this->bank = bank;
}
CheckingAccount::CheckingAccount() : Account("DefaultID", 0.0, "DefaultOwner") {}
CheckingAccount::CheckingAccount(const std::string& id, double initialBalance, const std::string& owner, Bank* bank)
    : Account(id, initialBalance, owner), bank(bank) {}

CheckingAccount::~CheckingAccount() {}
CheckingAccount::CheckingAccount(const CheckingAccount& other) : Account(other) {}
CheckingAccount& CheckingAccount::operator=(const CheckingAccount& other) {
    if (this != &other) {
        Account::operator=(other);
    }
    return *this;
}

void CheckingAccount::accessAccount() {
    std::cout << "---------------------------------\n";
    std::cout << "Checking Account: " << accountID << "\n";
    std::cout << "Owner: " << owner << "\n";
    std::cout << "Balance: ¥" << std::fixed << std::setprecision(2) << balance << "\n";
    std::cout << "Transactions:\n";
    for (const auto& transaction : transactions) {
        transaction.print();
    }
    std::cout << "---------------------------------\n";
    std::cout <<"options: \n";
    std::cout << "1. Deposit\n";
    std::cout << "2. Withdraw\n";
    std::cout << "3. Transfer\n";
    std::cout << "4. View transaction history\n";
    std::cout << "5. Generate bank account report\n";
    std::cout << "6. Return to customer page\n";

int choice1;
std::cout << "Enter your choice: ";
std::cin >> choice1;

if (std::cin.fail()) {
    std::cin.clear();
    std::cin.ignore(100, '\n');
    std::cout << "Invalid input. Please enter a number.\n";
}
if (choice1 < 1 || choice1 > 6) {
    std::cin.clear();
    std::cin.ignore(100, '\n');
    std::cout << "Invalid choice. Please try again.\n";
}

double amount;
std::string toAccountID, note;
Customer* toCustomer = nullptr; 
CheckingAccount* tocheckingAccount = nullptr; // Declare checkingAccount here 
SavingsAccount* tosavingsAccount = nullptr; // Declare savingsAccount here
Account* targetAccount = nullptr;

switch (choice1) {
    case 1:
        std::cout << "Enter the amount to deposit: ";
        std::cin >> amount;
        deposit(amount);
        std::cin.ignore(100, '\n');
        break;
    case 2:
        std::cout << "Enter the amount to withdraw: ";
        std::cin >> amount;
        withdraw(amount);
        std::cin.ignore(100, '\n');
        break;
    case 3:
        std::cout << "Enter the amount to transfer: ";
        std::cin >> amount;
        std::cin.ignore(100, '\n'); 
        std::cout << "Enter the account ID to transfer to: ";
        std::getline(std::cin, toAccountID);
        
        tocheckingAccount = bank ->findCheckingAccount(toAccountID);
        tosavingsAccount = bank ->findSavingsAccount(toAccountID);
        if (tosavingsAccount) {
            targetAccount = tosavingsAccount;
            std::cout << "Enter the note for the transfer: ";
            std::getline(std::cin, note);
            transfer(targetAccount, amount, note); 
            break;
        }
        if (!tocheckingAccount) {
            std::cout << "No  account found for this customer.\n";
            break;
        }
        targetAccount = tocheckingAccount;
        std::cout << "Enter the note for the transfer: ";
        std::getline(std::cin, note);
        transfer(targetAccount, amount, note); 
        break;
    case 4:
        std::cout << "Transaction history:\n";
        for (const Transaction& transaction : transactions) {
            transaction.print();
        }
        break;
    case 5:
        std::cout << "Generating bank account report...\n";
        bank->generateAccountReport(accountID); 
        std::cout << "Bank account report generated successfully.\n";
        break;
    case 6:
        std::cout << "Returning to customer page...\n";
        std::cin.ignore(100, '\n');
        break;
}


}